package com.nx.platform.openentry.annotation.parser;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nx.platform.openentry.annotation.ClassType;

/**
 * @author fcl
 * @version 创建时间：2017-6-12 下午8:01:29
 * 
 */
public class PacakgeScanUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(PacakgeScanUtil.class);
    
    private static final String DEFAULT_SUFFIX_CLASS = ".class";
    
    private static final char DEFAULT_POINT = '.';
    
    private static final char DEFAULT_SLASH = '/';
    
    /**
     * For scf
     *
     *            待扫描服务的包根路径 com
     *            待扫描服务目标包名称，默认解析次包下的类
     * @param annotationParser
     *            注解解析器
     */
    public static void scanScfPackage(AnnotationParser annotationParser) {
        
        String userDir = System.getProperty("user.dir");
        String rootPath = userDir + "/../";
        String serviceName = System.getProperty("scf.service.name");
        
        String serviceFolderPath = rootPath + "service/deploy/" + serviceName;
        // 是否循环迭代
        boolean recursive = true;
        logger.info("scanScfPackage serviceFolderPath " + serviceFolderPath);
        
        File serviceJarFile = new File(serviceFolderPath);
        
        logger.info("scanScfPackage serviceJarFile " + serviceJarFile.getAbsolutePath());
        
        File[] files = serviceJarFile.listFiles();
        
        String jarPath = "";
        for (int i = 0; files != null && i < files.length; i++) {
            if (files[i].getName().endsWith(".jar")) {
                jarPath = files[i].getAbsolutePath();
                logger.info("scanScfPackage jarPath " + jarPath);
            }
        }
        
        URL urlJar;
        try {
            urlJar = new URL("jar:file:" + jarPath + "!/");
            logger.info("scanScfPackage urlJar " + urlJar.getPath());
            
            String protocol = urlJar.getProtocol();
            
            if (ClassType.jar.name().equals(protocol)) {
                JarFile jar;
                jar = ((JarURLConnection)urlJar.openConnection()).getJarFile();
                Enumeration<JarEntry> entries = jar.entries();
                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    String name = entry.getName();
                    if (name.charAt(0) == DEFAULT_SLASH) {
                        name = name.substring(1);
                    }
                    
                    int idx = name.lastIndexOf(DEFAULT_SLASH);
                    String packageName = "";
                    if (idx != -1) {
                        packageName = name.substring(0, idx).replace(DEFAULT_SLASH, DEFAULT_POINT);
                    }
                    if ((idx != -1) || recursive) {
                        if (name.endsWith(DEFAULT_SUFFIX_CLASS) && !entry.isDirectory()) {
                            String className = name.substring(packageName.length() + 1, name.length() - 6);
                            try {
                                Class<?> clazz = Class.forName(packageName + DEFAULT_POINT + className);
                                logger.info("scanScfPackage className:" + packageName + DEFAULT_POINT + className);
                                
                                annotationParser.execute(clazz);
                                
                            } catch (ClassNotFoundException e) {
                                
                            }
                        }
                    }
                    
                }
            }
            
        } catch (MalformedURLException e) {
            logger.error("scanScfPackage urlJar error", e);
        } catch (IOException e) {
            logger.error("scanScfPackage urlJar error", e);
        }
        
    }
    
}
